home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Games Collection 1 / software vault.zip / software vault / CDR10 / XLIB06.ZIP / XLIBTL02 / XTSRTOOL.C < prev    next >
C/C++ Source or Header  |  1993-05-22  |  17KB  |  571 lines

  1. /*--------------------------------------------------------------------------*
  2.  | XTSRTOOL.C                                                               |
  3.  |   contains main, interrupt handling, and DOS interface routines          |
  4.  |   for the XLIB TSR utility capture program.                              |
  5.  | WARNING:                                                                 |
  6.  |   STACK CHECKING MUST BE OFF AS WELL AS REGISTER VARIABLES DURING        |
  7.  |   COMPILATION.                                                           |
  8.  | Tsr code based on TC_TSR                                                 |
  9.  *--------------------------------------------------------------------------*/
  10.  
  11. #include <dos.h>
  12. #include <conio.h>
  13. #include <alloc.h>
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <stdlib.h>
  17. #include <dir.h>
  18. #include "xtsrmous.h"
  19.  
  20. typedef unsigned char byte;
  21.  
  22. #define    TRUE      (1)
  23. #define    FALSE     (0)
  24.  
  25. #define  SAVE        (0)
  26. #define  RESTORE     (1)
  27.  
  28. #define  ON          (1)
  29. #define  OFF         (0)
  30.  
  31. #define  MIN_Y       (0)
  32. #define  MIN_X       (0)
  33.  
  34. #define  MAX_Y       (24)
  35. #define  MAX_X       (79)
  36.  
  37. #define   ALT        (8)
  38. #define   SCAN_CODE_GRAB (55) /* the '*' key on the right keypad    */
  39. #define   SCAN_CODE_CFG  (29) /* the 'ctrl' key on the right keypad */
  40. /* ie for configuration use Alt-Ctrl for grab use Alt-Kpd'*'        */
  41.  
  42. #define   INST_CODE_SET  (0x5156)  /* Uniqe id of BMP_GRAB                */
  43. #define   INST_CODE_RET  (0x5157)  /* Unique return signature of BMP_GRAB */
  44.  
  45.  
  46. #define   cli()     asm cli
  47. #define   sti()     asm sti
  48.  
  49. void do_main_task(void);
  50. void main_task(void);
  51.  
  52.  
  53. #define CONFIG_MODE 0
  54. #define GRAB_MODE   1
  55.  
  56. #define MEM_REQUIRED  950
  57.  
  58. #define COPY_PUT 0
  59. #define BUFF_SIZE (64 * 48) /* size of the largest mosaic */
  60.  
  61. /* XTSRUTIL imports */
  62. extern int get_video_mode(void);
  63. extern void m13h_rect(int x, int y, int color);
  64. extern void get_13h_rect(int x,int y, char *dest);
  65. extern void put_13h_rect(int x,int y, char *src);
  66. extern void get_line(int y, char *dest);
  67.  
  68. char bmsave[BUFF_SIZE];
  69. char fname[100];
  70. char path[80];
  71. /*------------------------------------------------------------------------*
  72.  |                           GLOBAL VARIABLES                             |
  73.  *------------------------------------------------------------------------*/
  74.  
  75. void interrupt (* old_intr_0x09)();      /* pointer to old interrupt 0x9  */
  76. void interrupt (* old_intr_0x28)();      /* pointer to old interrupt 0x28 */
  77. void interrupt (* old_intr_0x11)();      /* pointer to old interrupt 0x11 */
  78. unsigned far * EquipList=MK_FP(0x0000,0x0410); /* pointer to equip list   */
  79. unsigned _heaplen = 1;                   /* set minimum heap size         */
  80.  
  81. unsigned c_ss, c_sp,c_psp;  /* c_ss, c_sp are used to save  stack         */
  82. unsigned save_ss, save_sp;  /* save_ss and save_sp are used to save the   */
  83.                             /* active stack                               */
  84.  
  85. byte activation_mode; /* Determined by activation key                     */
  86. int x=0,
  87.     y=0,
  88.     width=16,
  89.     height=16,
  90.     pwidth = 16,
  91.     pheight = 16,
  92.     color=16;
  93.  
  94. byte active = FALSE;  /* program active flag (to prevent recursion)       */
  95. byte wanted = FALSE;  /* wanted is set to TRUE if the Hot key was pressed */
  96.                       /* but the program could not be activated           */
  97.  
  98. byte far * dos_active;                        /* pointer to DOS busy flag */
  99. byte far * shift_byte = (byte far *) 0x00400017L; /* pointer to keyboard  */
  100.                                                   /* status byte          */
  101.  
  102. char capture_mode='L';
  103. int lbm_count=0;
  104. int pal_count=0;
  105. int scr_count=0;
  106.  
  107. void build_name(){
  108.   switch (capture_mode) {
  109.     case 'L':sprintf(fname,"%sGRAB%04d.%s",path,lbm_count,"LBM"); break;
  110.     case 'P':sprintf(fname,"%sGRAB%04d.%s",path,pal_count,"PAL"); break;
  111.     case 'S':sprintf(fname,"%sGRAB%04d.%s",path,scr_count,"SCR"); break;
  112.   }
  113. }
  114.  
  115. void error_buzz(){
  116.   /* Error Buzz - Can only capture while in mode 13x */
  117.      sound(100); delay(200); nosound();
  118. }
  119.  
  120. void width_warning(){
  121.   if (width%4!=0){
  122.     printf("WARNING:The resulting LBM cannot be converted to a PBM\n");
  123.     printf("        The width is not a multiple of 4\n");
  124.   }
  125. }
  126.  
  127. void configure(){
  128.   static firsttime=1;
  129.   unsigned mcbseg;
  130.   struct SREGS seg;
  131.   union REGS regs;
  132.   char ch;
  133.   int old_h=height,old_w=width;
  134.   int * work_count_ptr;
  135.   printf("Select mode\n P)alette  L)BM  S)creen");
  136.   if (!firsttime) printf("  R)eset-count Q)uit");
  137.   printf(": ");
  138.   do{
  139.     ch=toupper(getc(stdin));
  140.   } while(ch < ' ' || ch > 'Z');
  141.   switch (toupper(ch)) {
  142.     case 'L':
  143.        capture_mode='L';
  144.        printf("\nLinear Bitmap capture mode\n  Width : ");
  145.        scanf("%d",&pwidth);
  146.        printf("  Height: ");
  147.        scanf("%d",&pheight);
  148.        printf("  Cursor Color: ");
  149.        scanf("%d",&color);
  150.        if(((long)width)*((long)height) > BUFF_SIZE) {
  151.          width=old_w;
  152.          height=old_h;
  153.        }
  154.        printf("\nSIZE= %dx%d cursor rect. color = %d\n",width,height,color);
  155.        build_name();
  156.        printf("Next output file is: '%s'\n",fname);
  157.        width_warning();
  158.        break;
  159.     case 'P':
  160.        capture_mode='P';
  161.        printf("\nPallete capture mode\n");
  162.        build_name();
  163.        printf("Next output file is: '%s'\n",fname);
  164.        break;
  165.     case 'S':
  166.        capture_mode='S';
  167.        printf("\nScreen capture mode\n");
  168.        build_name();
  169.        printf("Next output file is: '%s'\n",fname);
  170.        break;
  171.     case 'Q':
  172.        if (firsttime) break;
  173.        printf("\nQuitting XTSRTOOL. Bye...\n");
  174.        setvect( 0x09, old_intr_0x09 );
  175.        setvect( 0x28, old_intr_0x28 );
  176.        setvect( 0x11, old_intr_0x11 );
  177.        regs.h.ah=0x52;
  178.        intdos(®s,®s);
  179.        mcbseg=_ES;
  180.        mcbseg=peek(mcbseg,regs.x.bx-2);
  181.        segread(&seg);
  182.        while (peekb(mcbseg,0)==0x4D){
  183.      if (peek(mcbseg,1) == c_psp){
  184.        regs.h.ah=0x49;
  185.        seg.es=mcbseg+1;
  186.        intdosx(®s,®s,&seg);
  187.      }
  188.      mcbseg +=peek(mcbseg,3)+1;
  189.        }
  190.        exit(0);
  191.        break;
  192.     default: switch(capture_mode){
  193.            case 'L': printf("\nCurrently in LBM capture mode (%dx%d)\n",
  194.              width,height);
  195.              break;
  196.            case 'P': printf("\nCurrently in PALETTE capture mode\n");
  197.              break;
  198.            case 'S': printf("\nCurrently in SCREEN capture mode\n");
  199.              break;
  200.          };
  201.          if (toupper(ch)=='R'){
  202.            switch(capture_mode){
  203.          case 'L': work_count_ptr=&lbm_count;
  204.                break;
  205.          case 'P': work_count_ptr=&pal_count;
  206.                break;
  207.          case 'S': work_count_ptr=&pal_count;
  208.                break;
  209.            };
  210.            printf("\nCurrent File count = %d  Enter new count:",*work_count_ptr);
  211.            scanf("%d",work_count_ptr);
  212.          }
  213.          build_name();
  214.          printf("Next output file is: '%s'\n",fname);
  215.          width_warning();
  216.          break;
  217.   }
  218.   firsttime=0;
  219. }
  220.  
  221.  
  222. void write_LBM(){
  223.   FILE *f;
  224.   int dummy;
  225.   int top, left;
  226.  
  227.   width = pwidth;
  228.   height = pheight;
  229.  
  230.   x=MouseX,y=MouseY;
  231.   HideMouse();
  232.   get_13h_rect(x,y,bmsave);
  233.   m13h_rect(MouseX,MouseY,color);
  234.   do{
  235.     MouseXY();
  236.     if (MouseX !=x || MouseY != y) {
  237.       put_13h_rect(x,y,bmsave);
  238.       x=MouseX,y=MouseY;
  239.       if (x+width>320) {
  240.         x=320-width;
  241.         MouseToXY(x,y);
  242.       }
  243.       if (y+height>200) {
  244.         y=200-height;
  245.         MouseToXY(x,y);
  246.       }
  247.       get_13h_rect(x,y,bmsave);
  248.       m13h_rect(x,y,color);
  249.     }
  250.   } while (!LeftPressed && !RightPressed);
  251.  
  252. /* find lower-right corner */
  253.   left = x;
  254.   top = y;
  255.   x = left + width;
  256.   y = top + height;
  257.  
  258.   while (LeftPressed)
  259.     MouseXY();
  260.  
  261.   MouseToXY(x, y);
  262.  
  263.   if (!RightPressed) {
  264.     do {
  265.     MouseXY();
  266.     if (MouseX != x || MouseY != y) {
  267.       put_13h_rect(left,top,bmsave);
  268.       x = MouseX;
  269.       if (x - left < 2)
  270.         x = left + 2;
  271.       if (x - left > 63)
  272.         x = left + 63;
  273.  
  274.       y = MouseY;
  275.       if (y - top < 2)
  276.         y = top + 2;
  277.       if (y - top > 47)
  278.         y = top + 47;
  279.  
  280.       width = x - left;
  281.       height = y - top;
  282.  
  283.       get_13h_rect(left,top,bmsave);
  284.       m13h_rect(left,top,color);
  285.       MouseToXY(x, y);
  286.     }
  287.     } while (!LeftPressed && !RightPressed);
  288.   }
  289.  
  290.   if (LeftPressed) {
  291.     build_name();
  292.     if (f=fopen(fname,"wb")) {
  293.       if(!fwrite(bmsave,width*height+2,1,f)) {
  294.         fclose(f);
  295.         error_buzz();
  296.       } else {
  297.         fclose(f);
  298.         lbm_count++;
  299.       }
  300.     } else error_buzz();
  301.   }
  302.       MouseToXY(x - 1, y - 1);
  303.  
  304.   while (LeftPressed)
  305.     MouseXY();
  306.  
  307.   put_13h_rect(left,top,bmsave);
  308.   ShowMouse();
  309. }
  310.  
  311. void write_SCR(){
  312.   FILE *f;
  313.   int i;
  314.   build_name();
  315.   if (f=fopen(fname,"wb")){
  316.     for (i=0;i<200;i++){
  317.       get_line(i,bmsave);
  318.       if(!fwrite(bmsave,320,1,f)) {
  319.     fclose(f);
  320.     error_buzz();
  321.     return;
  322.       }
  323.     }
  324.     fclose(f);
  325.     scr_count++;
  326.   } else error_buzz();
  327. }
  328.  
  329. void write_PAL(){
  330.   FILE *f;
  331.   char far * scrn;
  332.   x_get_pal_raw(MK_FP(_DS,bmsave),256,0);
  333.   if (f=fopen(fname,"wb")){
  334.     if(!fwrite(bmsave,256*3,1,f)) {
  335.       fclose(f);
  336.       error_buzz();
  337.     } else {
  338.        fclose(f);
  339.        pal_count++;
  340.     }
  341.   } else error_buzz();
  342. }
  343.  
  344. void main_task(void){
  345.   int video;
  346.   char ch;
  347.   video=get_video_mode();
  348.   if (activation_mode==CONFIG_MODE){
  349.     if (video==3){
  350.       printf("\n┌──────────────────────────────────────────────────────────────┐\n");
  351.       printf(  "│XTSRTOOL - Mode 13x TSR screen/pallete/LBM capture utility    │\n");
  352.       printf(  "└──────────────────────────────────────────────────────────────┘\n\n");
  353.  
  354.       configure();
  355.     } else {
  356.      /* Error Buzz - Can only configure while in text mode */
  357.      sound(100); delay(200); nosound();
  358.     }
  359.   } else {
  360.     if (video == 0x13) {
  361.        /* beep to let you know you're in grab mode */
  362.        sound(800); delay(70); nosound();
  363.        if (capture_mode=='L') write_LBM();
  364.        else if (capture_mode=='P') write_PAL();
  365.        else if (capture_mode=='S') write_SCR();
  366.     } else {
  367.       error_buzz();
  368.     }
  369.   }
  370. };
  371.  
  372. void title_screen(){
  373.   clrscr();
  374.   printf("┌──────────────────────────────────────────────────────────────┐\n");
  375.   printf("│XTSRTOOL - Mode 13x TSR screen/pallete/LBM capture utility    │\n");
  376.   printf("╞══════════════════════════════════════════════════════════════╡\n");
  377.   printf("│HOTKEYS: ALT-KPD'*'  capture,  ALT-CTRL configure             │\n");
  378.   printf("│OUTPUT : GRABnnnn.LBM   -  xlib compatible linear bitmap mode │\n");
  379.   printf("│         GRABnnnn.PAL   -  xlib compatible raw palette mode   │\n");
  380.   printf("│         GRABnnnn.SCR   -  raw screen dump                    │\n");
  381.   printf("└──────────────────────────────────────────────────────────────┘\n\n");
  382. }
  383.  
  384.  
  385. /*------------------------------------------------------------------------*
  386.  |                       Keyboard interrupt handler                       |
  387.  *------------------------------------------------------------------------*/
  388.  
  389. void kbd_reset(void){    /* Reset Keyboard and programable interrupt      */
  390.                          /* controller (PIC)                              */
  391.      register char x;
  392.      x = inp(0x61);
  393.      outportb(0x61, (x | 0x80));
  394.      outportb(0x61, x);
  395.      cli();
  396.      outportb(0x20, 0x20);
  397.      sti();
  398. }/* kbd_reset */
  399.  
  400. int in_int08=0,int_09_stolen=0;
  401.  
  402. void interrupt intr_0x09(){  /* interrupt 9 handler (whenever a key is    */
  403.                              /* pressed control arrives hear)             */
  404.      register char x;
  405.  
  406.  
  407.      sti();
  408.      x = inp(0x60);                   /* read keyboard data port          */
  409.      if ( ( !active )        &&       /* if the program is not active and */
  410.       ( x==SCAN_CODE_GRAB||
  411.         x==SCAN_CODE_CFG) &&       /* x == hot key scan code and     */
  412.           ( ((*shift_byte) & ALT) != 0) /* the ALT key is pressed       */
  413.      )
  414.      {
  415.        activation_mode=(x==SCAN_CODE_GRAB);
  416.        active = TRUE;        /* set active to prevent recursion           */
  417.        kbd_reset();          /* reset keyboard controller and PIC         */
  418.        if (!(*dos_active)){  /* if DOS is not active then do main task    */
  419.          wanted = FALSE;
  420.          do_main_task();
  421.        }
  422.        else wanted = TRUE;   /* else set wanted flag to be processed via  */
  423.                              /* interrupt 0x28                            */
  424.        active = FALSE;
  425.      }
  426.      else {
  427.     (* old_intr_0x09)(); /* call old interrupt 9 handler            */
  428.      }
  429.  
  430. } /* intr_0x09 */
  431.  
  432.  
  433. /*------------------------------------------------------------------------*
  434.  |                       Interrupt 0x28 handler                           |
  435.  *------------------------------------------------------------------------*/
  436. void interrupt intr_0x28(){
  437.      void interrupt (* curr_intr_0x09)();
  438.      (* old_intr_0x28)(); /* call old interrupt 0x28(to give other memory */
  439.                           /* resident programs a chance to pop-up !)      */
  440.      if (wanted){         /* if the wanted flag is set then do main task  */
  441.        wanted = FALSE;
  442.        active = TRUE;
  443.        sti();
  444.        do_main_task();
  445.        cli();
  446.        active = FALSE;
  447.      }  else {
  448.      }
  449.  
  450. } /* intr_0x28 */
  451.  
  452.  
  453. /*------------------------------------------------------------------------*
  454.  |                       Interrupt 0x11 handler                           |
  455.  | Int11 : Is used normally by the system to retrieve the equipment list  |
  456.  |      word. We use it to determine if this TSR is already loaded; if CX |
  457.  |      is equal to INST_CODE_SET, we set it to INST_CODE_RET, which is   |
  458.  |      then returned. Since CX is not used by Int11, and we load the     |
  459.  |      returned AX register with the equipment list word from low memory,|
  460.  |      the operation should be transparent to other programs.            |
  461.  *------------------------------------------------------------------------*/
  462.  
  463. void interrupt intr_0x11(unsigned bp, unsigned di, unsigned si,
  464.              unsigned ds, unsigned es, unsigned dx,
  465.              unsigned cx, unsigned bx, unsigned ax){
  466.      void interrupt (* curr_intr_0x11)();
  467.      (* old_intr_0x11)(); /* call old interrupt 0x28(to give other memory */
  468.               /* resident programs a chance to pop-up !)      */
  469.      sti();
  470.      if (_CX==INST_CODE_SET) cx=INST_CODE_RET;
  471.      ax=*EquipList;
  472.      cli();
  473.  
  474. } /* intr_0x11 */
  475.  
  476.  
  477.  
  478. /*------------------------------------------------------------------------*
  479.  |                       do_main_task                                     |
  480.  *------------------------------------------------------------------------*/
  481. void do_main_task(void){
  482.  
  483.      cli();                        /* disable interrupts                  */
  484.      save_ss = _SS; save_sp = _SP; /* save the current stack              */
  485.      _SS = c_ss; _SP = c_sp;       /* restore XTSRTOOL's stack            */
  486.      sti();                        /* enable interrupts                   */
  487.  
  488.      main_task();
  489.  
  490.      cli();                        /* disable interrupts                  */
  491.      _SS = save_ss; _SP = save_sp; /* restore stack                       */
  492.      sti();                        /* enable interrupts                   */
  493.  
  494. } /* do_main_task() */
  495.  
  496.  
  497.  
  498.  
  499. /*------------------------------------------------------------------------*
  500.  |                       get_dos_flag                                     |
  501.  *------------------------------------------------------------------------*/
  502.  
  503. byte far * get_dos_flag(void){   /* get a pointer to DOS busy flag        */
  504.      union  REGS  reg;
  505.      struct SREGS s_reg;
  506.  
  507.      reg.x.ax = 0x3400;                /* function 0x34 get DOS busy flag */
  508.      intdosx(®, ®, &s_reg);      /* call DOS (interrupt 0x21)       */
  509.      return( MK_FP(s_reg.es, reg.x.bx) ); /* return far pointer ES:BX     */
  510.  
  511. }/* get_dos_flag() */
  512.  
  513.  
  514. /*------------------------------------------------------------------------*
  515.  |                         program_size                                   |
  516.  *------------------------------------------------------------------------*/
  517.  
  518. unsigned program_size(void){   /* return the size of the current memory   */
  519.                            /* control block (in paragraphs)               */
  520.     return MEM_REQUIRED+(* ((unsigned far *) (MK_FP(_psp-1, 3))) ) ;
  521.  
  522. }/* program_size() */
  523.  
  524.  
  525.  
  526.  
  527. /*------------------------------------------------------------------------*
  528.  |                         main function                                  |
  529.  *------------------------------------------------------------------------*/
  530. main(){
  531.   union REGS regs;
  532.   char ch;
  533.  
  534.   c_ss = _SS; c_sp = _SP;         /* save XTSRTOOL'S stack               */
  535.   c_psp = _psp;
  536.   regs.x.cx = INST_CODE_SET;
  537.   int86(0x11,®s,®s);
  538.   if (regs.x.cx == INST_CODE_RET){
  539.     title_screen();
  540.     printf("\n XTSRTOOL already installed...  \n ");
  541.     exit(0);
  542.   }
  543.  
  544.   dos_active = get_dos_flag();    /* get a pointer to DOS busy flag       */
  545.  
  546.   old_intr_0x09 = getvect(0x09);  /* save old interrupt 0x09 vector       */
  547.   setvect( 0x09, intr_0x09 ); /* set interrupt 0x09 vector to 'intr_0x09' */
  548.   old_intr_0x28 = getvect(0x28);  /* save old interrupt 0x28 vector       */
  549.   setvect( 0x28, intr_0x28 ); /* set interrupt 0x28 vector to 'intr_0x28' */
  550.   old_intr_0x11 = getvect(0x11);  /* save old interrupt 0x28 vector       */
  551.   setvect( 0x11, intr_0x11 ); /* set interrupt 0x28 vector to 'intr_0x28' */
  552.   /* last */
  553.  
  554.   strcpy(path,"X:\\");
  555.   path[0]='A'+getdisk();
  556.   getcurdir(0,path+3);
  557.   if (strlen(path)>3) strcat(path,"\\");
  558.   title_screen();
  559.   configure();
  560.   InitMouse();
  561.   HideMouse();
  562.  
  563.   /* bug - sound usually doesnt work the first call so call it once  */
  564.   sound(1);
  565.   delay(1);
  566.   nosound();
  567.  
  568.   keep(0,  (program_size()));    /* terminate and stay resident              */
  569.  
  570. } /* main() */
  571.